trigger ONEN_Opp_GivingHistoryRollup on Opportunity (before delete, 
													after insert, after update) {

	system.debug ('TRIGGER FIRED');
	
	//set<id> OppsToProcess = new set <id> ();
	set<id> ConsToProcess = new set <id> ();
	set<id> AcctsToProcess = new set <id> ();

	boolean skipOpps = Trigger.isDelete ? true : false ;


	// first, make sure we have checked for contact role creation if necessary
	// (have to do this here to insure triggers happen in the right order)
	if ( Trigger.isInsert && ONEN_OppContactRoles.haveCheckedContactRoles == false ) {
		ONEN_OppContactRoles.CheckContactRoles ( trigger.newmap );	
	}

	// get opp rectype id's that DO NOT count as gifts
	// TBD refactor this to class method?
	set<string> nongiftRTNames = ONEN_Constants.OPP_RECTYPES_NOT_GIFT;
	set<id> nongiftRTids = new set<id> ();
	if ( nongiftRTNames != null ) {
		ONEN_RecordTypes rtlookup = new ONEN_RecordTypes ('Opportunity');
		for ( string thisRTName : nongiftRTNames ) {
			id rtid = rtlookup.GetRecordTypeId (thisRTName);
			nongiftRTids.add (rtid);
		}	
	}

	// new method to lookup individual acct id
	Id IndAcctId = ONEN_DefaultAccount.GetIndividualAccountId();
	//system.debug ('ind acct: ' + IndAcctId);
		
	// operate on those opps that are Won and either inserted/deleted 
	// or chgd date/Won status/amt
	// TBD what if rectype chgd??
	// TBD what if undeleted??
	for ( Opportunity thisOpp : Trigger.IsDelete ? Trigger.old : Trigger.new ) {
	
		if ( ( trigger.isInsert || trigger.IsDelete ) && thisOpp.IsWon == true && nongiftRTids.contains(thisOpp.RecordTypeId) == false ) {
			
			// for 'contact' opps, can't get the contactId from here, so grab the opp id
			// for 'account' opps, grab that accountId directly
			if ( thisOpp.AccountId != IndAcctId && thisOpp.AccountId != null ) {
				AcctsToProcess.add (thisOpp.AccountId);	
			} else {
				ConsToProcess.add (thisOpp.id);	
			}

		} else if ( trigger.isUpdate ) {		
			Opportunity oldOpp = trigger.oldmap.get (thisOpp.id);	
			if  ( 
				nongiftRTids.contains(thisOpp.RecordTypeId) == false &&
				( thisOpp.IsWon != oldOpp.IsWon || 	
				thisOpp.Amount != oldOpp.Amount || 	
				thisOpp.CloseDate != oldOpp.CloseDate || 	
				thisOpp.AccountId != oldOpp.AccountId ) 	
			 ) {
				if ( thisOpp.AccountId != IndAcctId && thisOpp.AccountId != null ) {
					AcctsToProcess.add (thisOpp.AccountId);	
				} else {
					ConsToProcess.add (thisOpp.id);	
				}
			 }
		}
	}
	
	system.debug ('opps to process (for contacts): ' + ConsToProcess.size() );
	system.debug ('accounts to process: ' + AcctsToProcess.size() );
	
	if ( ConsToProcess.size () > 0 ) {

		list<Contact> ConsToUpdate = ONEN_OppGivingRollup.RollupGivingTotalsToContacts ( ConsToProcess, skipOpps, nongiftRTids);
		update ConsToUpdate;
		
	}

}